const axios = require('axios')
const webpack = require('webpack')
const MemoryFs = require('memory-fs')
const path = require('path')
const proxy = require('koa-server-http-proxy')
const renderString = require('./renderString')

// 1.获取index.html文件
// 解决方法直接向client做http请求获取
// 2.启动server/index.js
// 使用webpack启动并编译，储存到缓存中:重新指定编译文件的存储方式
// 3.将访问逻辑与index.html和server-entry结合并返回页面
// 在缓存中读取server-entry文件内容，并使用module._copmon进行解析
// 4.处理资源访问的publicPatch问题
// 使用代理解决返回

const serverConfig = require('../../build/webpack.config.server')
const serverCompiler = webpack(serverConfig)
const mfs = new MemoryFs()
serverCompiler.outputFileSystem = mfs

let serverbundle

const NativeModule = require('module')
const vm = require('vm')

const getModuleFromString = (bundle, filename) => {
    const m = { exports: {} }
    const wrapper = NativeModule.wrap(bundle)
    const script = new vm.Script(wrapper, {
        filename: filename,
        displayErrors: true
    })
    const result = script.runInThisContext()
    result.call(m.exports, m.exports, require, m)
    return m
}

console.log('webpack build load server entry')
serverCompiler.watch({}, (err, stats) => {
    if (err) throw err
    stats = stats.toJson()
    stats.errors.forEach(err => console.error('err:', err))
    stats.warnings.forEach(warn => console.warn('warn:', warn))

    const bundlePath = path.join(
        serverConfig.output.path,
        serverConfig.output.filename
    )
    const bundle = mfs.readFileSync(bundlePath, 'utf-8')
    const m = getModuleFromString(bundle, 'server-entry.js')
    serverbundle = m.exports
    console.log('loading server entry success')
})

const getTemplate = () => {
    return new Promise((resolve, reject) => {
        axios.get('http://localhost:3030/public/index.pug')
            .then((res) => {
                resolve(res.data)
            })
            .catch(reject)
    })
}

module.exports = function (app, router) {
    app.use(proxy('/public', {
        target: 'http://localhost:3030'
    }))

    // router.all('', async (ctx, next) => {
    app.use(async (ctx, next) => {

        const session = ctx.session
        console.log('html-session', session)

        await getTemplate().then(template => {
            const result = renderString(serverbundle, template, ctx, next)
        })
        await next();
    });
}
